// 版权归Go作者所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// 此文件实现Ints的编码/解码。

package big

import (
	"bytes"
	"fmt"
)

// Gob编解码器版本。允许对编码进行向后兼容的更改。
const intGobVersion byte = 1

// GobEncode实现了gob。GobEncoder接口。
func (x *Int) GobEncode() ([]byte, error) {
	if x == nil {
		return nil, nil
	}
	buf := make([]byte, 1+len(x.abs)*_S) // 版本和符号位的额外字节
	i := x.abs.bytes(buf) - 1            // i>=0 
	b := intGobVersion << 1              // 为符号位
	if x.neg {
		b |= 1
	}
	buf[i] = b
	return buf[i:], nil
}

// GODECODE实现gob。解码接口。
func (z *Int) GobDecode(buf []byte) error {
	if len(buf) == 0 {
		// 另一方发送了一个零或默认值。
		*z = Int{}
		return nil
	}
	b := buf[0]
	if b>>1 != intGobVersion {
		return fmt.Errorf("Int.GobDecode: encoding version %d not supported", b>>1)
	}
	z.neg = b&1 != 0
	z.abs = z.abs.setBytes(buf[1:])
	return nil
}

// MarshalText实现了编码。TextMarshaler接口。
func (x *Int) MarshalText() (text []byte, err error) {
	if x == nil {
		return []byte("<nil>"), nil
	}
	return x.abs.itoa(x.neg, 10), nil
}

// UnmarshalText实现编码。TextUnmarshaler接口。
func (z *Int) UnmarshalText(text []byte) error {
	if _, ok := z.setFromScanner(bytes.NewReader(text), 0); !ok {
		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
	}
	return nil
}

// JSON封送器仅用于API向后兼容性
// （明确查找这两种方法的程序）。JSON只适用于TextMarshaler。

// MarshallJSON实现了json。封送处理程序接口。
func (x *Int) MarshalJSON() ([]byte, error) {
	return x.MarshalText()
}

// UnmarshalJSON实现json。解组器接口。
func (z *Int) UnmarshalJSON(text []byte) error {
	// 忽略null，就像在主JSON包中一样。
	if string(text) == "null" {
		return nil
	}
	return z.UnmarshalText(text)
}
